#include <malloc/_malloc.h>

#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <iostream>
#define MAX_N 20

typedef struct Vector {
    int capacity;
    int size;
    int *data; 
} Vector;
// 初始化
Vector *initVector(int n) {
    Vector *p = (Vector *)malloc(sizeof(Vector));
    p->capacity = n;
    p->size = 0;
    p->data = (int *)malloc(sizeof(int) * n);
    return p;
}
// 销毁
void destroyVector(Vector *p) {
    if (p == nullptr)
        return;
    free(p->data);
    free(p);
    p = nullptr;
    return;
}
// 扩容
bool expandVector(Vector *p) {
    if(p == nullptr) return false;
    int *tmp = (int *)realloc(p->data, sizeof(int) * 2 * p->capacity);
    if(tmp == nullptr) return false;
    p->data = tmp;
    std::cout << "Expand" << p->capacity << " to" << 2 * p->capacity << std::endl;
    std::cout << std::endl;
    p->capacity *= 2; 
    return true;
}
// 插入
bool insert(Vector *p, int pos, int val) {
    if (p == nullptr)
        return false;
    if (pos < 0 || pos > p->size)
        return false;
    if(p->capacity == p->size && expandVector(p))
        return false;
    for (int i = p->size - 1; i >= pos; i--) {
        p->data[i + 1] = p->data[i];
    }
    p->data[pos] = val;
    p->size++;
    return true;
}
// 删除
bool erase(Vector *p, int pos) {
    if (p == nullptr)
        return false;
    if (pos < 0 || pos >= p->size || p->size == 0)
        return false;
    for (int i = pos; i < p->size - 1; i++) {
        p->data[i] = p->data[i + 1];
    }
    p->size--;
    return true;
}

void printVector(Vector *p) {
    if (p == nullptr)
        return;
    int len = 0;
    for (int i = 0; i < MAX_N; i++) {
        len += printf("%3d|", i);
    }
    printf("\n");
    for (int i = 0; i < len; i++) {
        printf("-");
    }
    printf("\n");
    for (int i = 0; i < p->size; i++) {
        printf("%3d|", p->data[i]);
    }
    printf("\n\n");
    return;
}

int main() {
    srand(time(0));
    Vector *ptr = initVector(2);
    for (int i = 1; i <= MAX_N; i++) {
        int op = rand() % 4, pos, val;
        switch (op) {
            case 0:
            case 1:
            case 2:
                pos = rand() % (ptr->size + 2);
                val = rand() % 100;
                printf("%d : Insert %d at %d\n\n", i, val, pos);
                if (insert(ptr, pos, val))
                    printVector(ptr);
                else
                    std::cout << "Failed to Insert\n" << std::endl;
                break;
            case 3:
                pos = rand() % (ptr->size + 2);
                printf("%d : Erase item at %d\n\n", i, pos);
                if (erase(ptr, pos))
                    printVector(ptr);
                else
                    std::cout << "Failed to Erase\n" << std::endl;
                break;
        }
    }
    // for (int i = 0; i < MAX_N; i++) {
    //     insert(ptr, i, rand() % 100);
    // }
    // printVector(ptr);
    destroyVector(ptr);
    return 0;
}